package editor.widgets;

import editor.Images;
import util.StringUtil;
import widgets.CustomButton;
import widgets.ImageButton;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

/**
 * This class is for displaying messages to the user.
 *
 * @author Neil Dickson
 */
public class MessagePopup extends JDialog implements ActionListener {
	private	final Frame		rootParent;
	private	Image			image;
	private	String[]		text;
	private	ImageButton[]	buttons;
	private	int				selected;

	public static final int		NONE_SELECTED	= -1;
	public static final int		OK				= 0;
	public static final int		CANCEL			= 1;

	public final int			horizontalSpace;
	public final int			verticalSpace;

	public static final Font	FONT				=	new Font("Arial",Font.PLAIN,14);
	public static final int		LINE_HEIGHT			=	(int) (FONT.getSize()*1.3);
	public static final Font	HEADER_FONT			=	new Font("Arial",Font.BOLD,16);

	public static final Color	TRANSPARENT			=	new Color(0,true);
	public static final Color	ALMOST_TRANSPARENT	=	new Color(0x00FFFFFF,true);
	public static final Color	BACKGROUND_COLOUR	=	Color.WHITE;
	public static final Color	FONT_COLOUR			=	Color.BLACK;
	public static final Color	LINE_COLOUR			=	new Color(0xC0C0C0);
	public static final int		SHADOW_OPACITY		=	0xC0;

	public static final int[]	BUTTONS_OK			= new int[] {OK};
	public static final int[]	BUTTONS_OK_CANCEL	= new int[] {OK,CANCEL};

	public MessagePopup(Frame rootParent,Image image,String text) {
		this(rootParent,image,text,BUTTONS_OK);
	}
	public MessagePopup(Frame rootParent,Image image,String text,int[] buttonTypes) {
		this(rootParent,image,text,buttonTypes,true);
	}
	public MessagePopup(Frame rootParent,Image image,String text,int[] buttonTypes,boolean isModal) {
		super(rootParent,isModal);
		this.rootParent = rootParent;
		setBackground(Color.WHITE);
		setLayout(new BorderLayout(0,0));
		setResizable(false);
		horizontalSpace = 20;
		verticalSpace = 12;
		this.image = image;
		this.text = StringUtil.getLines(text);
		selected = NONE_SELECTED;

		buttons = new ImageButton[buttonTypes.length];
		for (int i=0;i<buttons.length;++i) {
			if (buttonTypes[i]==OK) {
				buttons[i] = new ImageButton(Images.OK_UP,Images.OK_HOVER,Images.OK_DOWN,Images.OK_DISABLED);
			}
			else if (buttonTypes[i]==CANCEL) {
				buttons[i] = new ImageButton(Images.CANCEL_UP,Images.CANCEL_HOVER,Images.CANCEL_DOWN,Images.CANCEL_DISABLED);
			}
			buttons[i].addActionListener(this);
		}

		updateSize();

		JPanel bottomPanel = new JPanel();
		for (CustomButton button : buttons) {
			bottomPanel.add(button);
		}
		bottomPanel.setBackground(Color.WHITE);
		add(bottomPanel,BorderLayout.SOUTH);

		JPanel textPanel = new JPanel(null) {
			public void paintComponent(Graphics g) {
//				super.paintComponent(g);
				g.setColor(Color.WHITE);
				g.fillRect(0,0,getWidth(),getHeight());
				Graphics2D g2 = (Graphics2D)g;
				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

				int textStartY = verticalSpace;
				if (MessagePopup.this.image!=null) {
					g2.drawImage(MessagePopup.this.image,(getWidth()-MessagePopup.this.image.getWidth(null))>>>1, verticalSpace,null);
					textStartY += MessagePopup.this.image.getHeight(null)+ verticalSpace;
				}

				g2.setFont(FONT);
				g2.setColor(FONT_COLOUR);
				textStartY += LINE_HEIGHT-FONT.getSize()/4-1;
				for (String line : MessagePopup.this.text) {
					g2.drawString(line, horizontalSpace,textStartY);
					textStartY += LINE_HEIGHT;
				}
				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
				for (int i=0;i<getComponentCount();++i) {
					getComponent(i).repaint();
				}
			}
		};
		add(textPanel, BorderLayout.CENTER);
	}

	public void setVisible(boolean b) {
		if (b) {
			updatePopupLocationMiddle();
		}
		super.setVisible(b);
	}

	public void actionPerformed(ActionEvent e) {
		for (int i=0;i<buttons.length;++i) {
			if (e.getSource()==buttons[i]) {
				setVisible(false);
				selected = i;
				break;
			}
		}
	}

	public int getSelected() {
		return selected;
	}

	public void setText(String text) {
		this.text = StringUtil.getLines(text);
		updateSize();
	}

	private void updateSize() {
		FontMetrics metrics = getFontMetrics(FONT);
		int width = 0;
		int height = 0;
		for (String line : text) {
			width = Math.max(width,metrics.stringWidth(line));
			height += LINE_HEIGHT;
		}

		if (image!=null) {
			width = Math.max(width,image.getWidth(null)/*+radius*/);
			height += image.getHeight(null)+ verticalSpace;
		}

		int buttonsWidth = 0;
		int buttonsHeight = 0;
		for (ImageButton button : buttons) {
			buttonsWidth += button.getWidth();
			buttonsHeight = Math.max(buttonsHeight, button.getHeight());
		}
		buttonsWidth += (buttons.length-1)* horizontalSpace;

		width = Math.max(width,buttonsWidth);
		height += buttonsHeight+ verticalSpace;

		width += horizontalSpace + horizontalSpace;// + shadowSpacing;
		height += 25 + verticalSpace + verticalSpace;// + shadowSpacing;

		setSize(width,height);

		int buttonsXOffset = 0;
		for (ImageButton button : buttons) {
			button.setLocation(((width - buttonsWidth)>>1)+buttonsXOffset,height/*-shadowSpacing*/-verticalSpace-button.getHeight());
			buttonsXOffset += button.getWidth() + horizontalSpace;
		}

		updatePopupLocationMiddle();
	}

	public void updatePopupLocationMiddle() {
		Point parentScreen = new Point(0,0);
		try {
			parentScreen = rootParent.getLocationOnScreen();
		}
		catch (Throwable t) {
			// Stuff gets thrown if the parent isn't visible yet
		}
		setLocation(new Point(((rootParent.getWidth()-getWidth())>>1)+parentScreen.x,((rootParent.getHeight()-getHeight())>>1) + parentScreen.y));
	}

	@Deprecated
	public void reshape(int x, int y, int width, int height) {
		if (x>=16000) {
			x = 0;
		}
		if (y>=16000) {
			y = 0;
		}
		Point parentScreen = new Point(0,0);
		try {
			parentScreen = rootParent.getLocationOnScreen();
		}
		catch (Throwable t) {
			// Stuff gets thrown if the parent isn't set yet or isn't visible yet
		}
		if (x<parentScreen.x) {
			x = parentScreen.x;
		}
		if (y<parentScreen.y) {
			y = parentScreen.y;
		}
		super.reshape(x, y, width, height);
	}

	public void keyReleased(KeyEvent e) {
		if (e.getKeyCode()==KeyEvent.VK_ENTER) {
			actionPerformed(new ActionEvent(buttons[0],ActionEvent.ACTION_PERFORMED,""));
		}
	}
}
